home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1992 …SCII & the Runetime Code / ADC Developer CD (1992-07) (''Butch ASCII And The Runtime Code'')_iso / Dev.CD 199207.iso / Developer Essentials / DTS Sample Code / System 7.0 Samples / MacShell / Window.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-12-04  |  18.2 KB  |  775 lines  |  [TEXT/MPS ]

  1. /*
  2. ** Apple Macintosh Developer Technical Support
  3. **
  4. ** Program:     MacShell
  5. ** File:        window.c
  6. ** Written by:  Eric Soldan
  7. **
  8. ** Copyright © 1990-1991 Apple Computer, Inc.
  9. ** All rights reserved.
  10. */
  11.  
  12.  
  13.  
  14. /*****************************************************************************/
  15.  
  16.  
  17.  
  18. #include "MacShell.h"            /* Get the MacShell includes/typedefs, etc.    */
  19. #include "MacShellCommon.h"        /* Get the stuff in common with rez.        */
  20. #include "MacShell.protos"        /* Get the prototypes for MacShell.            */
  21.  
  22. #ifndef __ERRORS__
  23. #include <Errors.h>
  24. #endif
  25.  
  26. #ifndef THINK_C
  27. #ifndef __SYSEQU__
  28. #include <SysEqu.h>
  29. #endif
  30. #endif
  31.  
  32. #ifdef THINK_C
  33. #include "Utilities.h"
  34. #else
  35. #ifndef __UTILITIES__
  36. #include <Utilities.h>
  37. #endif
  38. #endif
  39.  
  40.  
  41.  
  42. /*****************************************************************************/
  43.  
  44.  
  45.  
  46. static RgnHandle    gKeepUpdateRgn;
  47. static WindowPtr    gOldPort;
  48.  
  49. extern short        gPrintPage;        /* Non-zero means we are printing. */
  50.  
  51.  
  52.  
  53. /*****************************************************************************/
  54. /*****************************************************************************/
  55.  
  56.  
  57.  
  58. /* This function creates a new application window.  An application window
  59. ** contains a document which is referenced by a handle in the refCon field.
  60. */
  61.  
  62. #pragma segment Window
  63. OSErr    DoNewWindow(FileRecHndl frHndl, WindowPtr *retWindow, WindowPtr behind, short attributes)
  64. {
  65.     WindowPtr        oldPort, window;
  66.     ControlHandle    ctl;
  67.     Rect            ctlRect;
  68.     short            h, v;
  69.     OSErr            err;
  70.  
  71.     if (!frHndl) return(noErr);
  72.  
  73.     /* We will allocate our own window storage instead of letting the Window
  74.     ** Manager do it because GetNewWindow may load in temp. resources before
  75.     ** making the NewPtr call, and this can lead to heap fragmentation.
  76.     */
  77.  
  78.     GetPort(&oldPort);
  79.  
  80.     err = noErr;
  81.  
  82.     if (window = GetStaggeredWindow(rWindow, nil, FrontWindow(), behind, true)) {
  83.         SetPort(window);
  84.         SetWRefCon(window, (long)frHndl);
  85.         NewWindowTitle(window);
  86.  
  87.         (*frHndl)->fileState.window     = window;
  88.         (*frHndl)->fileState.attributes = attributes;
  89.         (*frHndl)->fileState.vScroll    = nil;
  90.         (*frHndl)->fileState.hScroll    = nil;
  91.  
  92.         (*frHndl)->fileState.hArrowVal = 16;    /* Default arrow value is 16. */
  93.         (*frHndl)->fileState.vArrowVal = 16;
  94.  
  95.         h = window->portRect.right;                /* Default document size is */
  96.         if (attributes & kwHScroll) h -= 15;    /* content less scrollbars. */
  97.         (*frHndl)->fileState.hDocSize = h;        /* We don't have to initialize the page */
  98.         v = window->portRect.bottom;            /* values since the scrollbars won't be */
  99.         if (attributes & kwVScroll) v -= 15;    /* active until the window is resized   */
  100.         (*frHndl)->fileState.vDocSize = v;        /* or these values are set elsewhere.   */
  101.  
  102.         if (attributes & kwHScroll) {        /* Caller wants a horizontal scrollbar... */
  103.             ctlRect = window->portRect;
  104.             --ctlRect.left;
  105.             ++ctlRect.right;
  106.             ctlRect.top = ++ctlRect.bottom - 16;
  107.             if (attributes & (kwHScrollLessGrow - kwHScroll +  kwGrowIcon)) ctlRect.right -= 15;
  108.             OffsetRect(&ctlRect, 0, -16384);
  109.             ctl = NewControl(window, &ctlRect, nil, true, 0, 0, 0, scrollBarProc, 0L);
  110.             if (ctl)
  111.                 (*frHndl)->fileState.hScroll = ctl;
  112.             else
  113.                 err = memFullErr;
  114.         }
  115.  
  116.         if (!err) {
  117.             if (attributes & kwVScroll) {        /* Caller wants a vertical scrollbar... */
  118.                 ctlRect = window->portRect;
  119.                 --ctlRect.top;
  120.                 ++ctlRect.bottom;
  121.                 ctlRect.left = ++ctlRect.right - 16;
  122.                 if (attributes & (kwVScrollLessGrow - kwVScroll +  kwGrowIcon)) ctlRect.bottom -= 15;
  123.                 OffsetRect(&ctlRect, 0, -16384);
  124.                 ctl = NewControl(window, &ctlRect, nil, true, 0, 0, 0, scrollBarProc, 0L);
  125.                 if (ctl)
  126.                     (*frHndl)->fileState.vScroll = ctl;
  127.                 else
  128.                     err = memFullErr;
  129.             }
  130.         }
  131.  
  132.         if (!err) {
  133.             err = (*((*frHndl)->fileState.initContentProc))(frHndl, window);
  134.             if (!err) {
  135.                 if (gPrintPage)
  136.                     MoveWindow(window, 16384, 16384, true);
  137.                         /* So the window can be hidden while printing, yet
  138.                         ** PrintMonitor can get the document name. */
  139.                 ShowWindow(window);
  140.                 if (gPrintPage)
  141.                     MoveWindow(window, 16384, 16384, true);
  142.                         /* Moving invisible windows to the front doesn't always
  143.                         ** get them to the front.  Now that it is visible, moving
  144.                         ** it will definitely get it to the front. */
  145.             }
  146.         }
  147.         else DisposeAnyWindow(window);
  148.     }
  149.     else err = memFullErr;
  150.  
  151.     SetPort(oldPort);
  152.     if (retWindow) *retWindow = window;
  153.  
  154.     return(err);
  155. }
  156.  
  157.  
  158.  
  159. /*****************************************************************************/
  160.  
  161.  
  162.  
  163. /* This function updates the window title to reflect the new document name.
  164. ** The new document name is stored in the fileState portion of the document.
  165. ** This is automatically set to 'Untitled # N' for new documents, and is
  166. ** updated when a user does a save-as.
  167. */
  168.  
  169. #pragma segment Window
  170. void    NewWindowTitle(WindowPtr window)
  171. {
  172.     FileRecHndl    frHndl;
  173.     Str255        wTitle;
  174.  
  175.     if (window) {
  176.         if (frHndl = (FileRecHndl)GetWRefCon(window)) {
  177.             pstrcpy((char *)wTitle, (char *)(*frHndl)->fileState.fss.name);
  178.             SetWTitle(window, wTitle);
  179.         }
  180.     }
  181. }
  182.  
  183.  
  184.  
  185. /*****************************************************************************/
  186.  
  187.  
  188.  
  189. /* This function returns the state of the window's document.  If the document
  190. ** is dirty, then true is returned.  If the document is clean, or the window
  191. ** has no document, then false is returned.
  192. */
  193.  
  194. #pragma segment Window
  195. Boolean    GetWindowDirty(WindowPtr window)
  196. {
  197.     FileRecHndl    frHndl;
  198.  
  199.     if (IsAppWindow(window))
  200.         if (frHndl = (FileRecHndl)GetWRefCon(window))
  201.             return((*frHndl)->fileState.docDirty);
  202.  
  203.     return(false);
  204. }
  205.  
  206.  
  207.  
  208. /*****************************************************************************/
  209.  
  210.  
  211.  
  212. /* This function sets the state of the window's document. */
  213.  
  214. #pragma segment Window
  215. void    SetWindowDirty(WindowPtr window)
  216. {
  217.     FileRecHndl    frHndl;
  218.  
  219.     if (IsAppWindow(window))
  220.         if (frHndl = (FileRecHndl)GetWRefCon(window))
  221.             (*frHndl)->fileState.docDirty = true;
  222. }
  223.  
  224.  
  225.  
  226. /*****************************************************************************/
  227.  
  228.  
  229.  
  230. /* Close all the windows.  This is called prior to quitting the application.
  231. ** This function returns true if all windows were closed.  The user may decide
  232. ** to abort a save, thus stopping the closing of the windows.  If the user
  233. ** does this, false will be returned, indicating that all windows were not
  234. ** closed after all.
  235. */
  236.  
  237. #pragma segment Window
  238. Boolean    DisposeAllWindows(void)
  239. {
  240.     WindowPtr    window;
  241.  
  242. #ifdef __SYSEQU__    
  243.     while (window = *(WindowPtr *)WindowList) {
  244. #else
  245.     while (window = (WindowPtr)WindowList) {
  246. #endif
  247.         /* While we have a front window, try closing it. */
  248.  
  249.         if (!DisposeOneWindow(window, iQuit)) return(false);
  250.             /* When DisposeOneWindow returns false, this means that the window
  251.             ** didn't close.  The only cause of this is if the window had a
  252.             ** document that needed saving, and the user cancelled the save.
  253.             ** If the window succeeded in getting closed, then we are
  254.             ** returned true.  Either way, we return the result.
  255.             */
  256.     }
  257.  
  258.     return(true);
  259. }
  260.  
  261.  
  262.  
  263. /*****************************************************************************/
  264.  
  265.  
  266.  
  267. /* Closes one window.  This window may be an application window, or it may be
  268. ** a system window.  If it is an application window, it may have a document
  269. ** that needs saving.
  270. */
  271.  
  272. #pragma segment Window
  273. Boolean    DisposeOneWindow(WindowPtr window, short saveMode)
  274. {
  275.     FileRecHndl    frHndl;
  276.     OSErr        err;
  277.  
  278.     if (window) {
  279.         if (IsAppWindow(window)) {
  280.             /* First, if the window is an application window, try saving
  281.             ** the document.  Remember that the user may cancel the save.
  282.             */
  283.  
  284.             if (frHndl = (FileRecHndl)GetWRefCon(window)) {
  285.  
  286.                 err = AppSaveDocument(frHndl, window, saveMode);
  287.                 if (err) {
  288.                     if (err != userCanceledErr)
  289.                         Alert(rErrorAlert, (ModalFilterProcPtr)alertFilter);
  290.                     return(false);
  291.                 }        /* Stop closing windows on error or user cancel. */
  292.  
  293.                 SendMessage(frHndl, kDisconnectMssg);
  294.                 AppDisposeDocument(frHndl);
  295.                     /* The document is saved, or the user doesn't care about
  296.                     ** that document, so dispose of the document.
  297.                     */
  298.             }
  299.         }
  300.         DisposeAnyWindow(window);
  301.     }
  302.  
  303.     return(true);
  304. }
  305.  
  306.  
  307.  
  308. /*****************************************************************************/
  309.  
  310.  
  311.  
  312. #pragma segment Window
  313. WindowPtr    SetFilePort(FileRecHndl frHndl)
  314. {
  315.     WindowPtr    oldPort;
  316.  
  317.     GetPort(&oldPort);
  318.     if (frHndl) SetPort((*frHndl)->fileState.window);
  319.     return(oldPort);
  320. }
  321.  
  322.  
  323.  
  324. /*****************************************************************************/
  325.  
  326.  
  327.  
  328. #pragma segment Window
  329. void    DoResizeWindow(WindowPtr window, short oldh, short oldv)
  330. {
  331.     FileRecHndl        frHndl;
  332.     WindowPtr        oldPort;
  333.     short            attributes;
  334.     Boolean            growIconSpace;
  335.     Rect            portRct, rct;
  336.     ControlHandle    hScroll, vScroll;
  337.     RgnHandle        updateRgn;
  338.  
  339.     if (!window) return;
  340.  
  341.     frHndl  = (FileRecHndl)GetWRefCon(window);
  342.     oldPort = SetFilePort(frHndl);
  343.     attributes    = (*frHndl)->fileState.attributes;
  344.     growIconSpace = (attributes & (kwGrowIcon | (kwHScrollLessGrow - kwHScroll) | (kwVScrollLessGrow - kwVScroll)));
  345.         /* growIconSpace true if window has grow icon or a blank space for one. */
  346.  
  347.     SetOrigin(0, 0);
  348.     portRct = window->portRect;
  349.  
  350.     if (growIconSpace) {
  351.         rct.left = (rct.right  = oldh) - 15;
  352.         rct.top  = (rct.bottom = oldv) - 15;
  353.         EraseRect(&rct);
  354.         InvalRect(&rct);
  355.         rct = portRct;
  356.         rct.left = rct.right  - 15;
  357.         rct.top  = rct.bottom - 15;
  358.         EraseRect(&rct);
  359.     }
  360.  
  361.     SetOrigin(0, -16384);
  362.     if (hScroll = (*frHndl)->fileState.hScroll) {
  363.         HideControl(hScroll);
  364.         rct = (*hScroll)->contrlRect;
  365.         MoveControl(hScroll, rct.left, portRct.bottom - 15 - 16384);
  366.         SizeControl(hScroll, rct.right - rct.left + (portRct.right - portRct.left - oldh), 16);
  367.     }
  368.     if (vScroll = (*frHndl)->fileState.vScroll) {
  369.         HideControl(vScroll);
  370.         rct = (*vScroll)->contrlRect;
  371.         MoveControl(vScroll, portRct.right - 15, rct.top);
  372.         SizeControl(vScroll, 16, rct.bottom - rct.top + (portRct.bottom - portRct.top - oldv));
  373.     }
  374.  
  375.     AdjustScrollBars(window);
  376.  
  377.     if (hScroll) ShowControl(hScroll);
  378.     if (vScroll) ShowControl(vScroll);
  379.  
  380.     SetOrigin(0, 0);
  381.     if (attributes & kwGrowIcon) DoDrawGrowIcon(window, false, false);
  382.  
  383.     BeginContent(window);
  384.     (*((*frHndl)->fileState.resizeContentProc))(window, oldh, oldv);
  385.     updateRgn = NewRgn();
  386.     CopyRgn(((WindowPeek)window)->updateRgn, updateRgn);
  387.     EndContent(window);
  388.     UnionRgn(updateRgn, ((WindowPeek)window)->updateRgn, ((WindowPeek)window)->updateRgn);
  389.     DisposeRgn(updateRgn);
  390.  
  391.     SetPort(oldPort);
  392. }
  393.  
  394.  
  395.  
  396. /*****************************************************************************/
  397.  
  398.  
  399.  
  400. #pragma segment Window
  401. void    DoDrawFrame(WindowPtr window)
  402. {
  403.     FileRecHndl        frHndl;
  404.     WindowPtr        oldPort;
  405.     short            attributes;
  406.     Rect            portRect;
  407.  
  408.     if (window) {
  409.  
  410.         frHndl  = (FileRecHndl)GetWRefCon(window);
  411.         oldPort = SetFilePort(frHndl);
  412.         SetOrigin(0, 0);
  413.         portRect = window->portRect;
  414.  
  415.         attributes = (*frHndl)->fileState.attributes;
  416.         if (attributes & kwGrowIcon) DoDrawGrowIcon(window, false, false);
  417.  
  418.         SetOrigin(0, -16384);
  419.         DoDrawControls(window, true);
  420.         SetOrigin(0, 0);
  421.         (*((*frHndl)->fileState.drawFrameProc))(frHndl, window);
  422.  
  423.         SetPort(oldPort);
  424.     }
  425. }
  426.  
  427.  
  428.  
  429. /*****************************************************************************/
  430.  
  431.  
  432.  
  433. #pragma segment Window
  434. RgnHandle    DoCalcFrameRgn(WindowPtr window)
  435. {
  436.     FileRecHndl        frHndl;
  437.     WindowPtr        oldPort;
  438.     RgnHandle        urgn, wrgn;
  439.     short            attributes, i;
  440.     Boolean            growIconSpace;
  441.     Rect            portRect, rct;
  442.     Point            l2g;
  443.     ControlHandle    ctl;
  444.  
  445.     urgn = NewRgn();
  446.     if (!window) return(urgn);
  447.  
  448.     frHndl  = (FileRecHndl)GetWRefCon(window);
  449.     oldPort = SetFilePort(frHndl);
  450.     SetOrigin(0, 0);
  451.  
  452.     (*((*frHndl)->fileState.calcFrameRgnProc))(frHndl, window, urgn);
  453.  
  454.     portRect      = window->portRect;
  455.     attributes    = (*frHndl)->fileState.attributes;
  456.     growIconSpace = (attributes & (kwGrowIcon | (kwHScrollLessGrow - kwHScroll) | (kwVScrollLessGrow - kwVScroll)));
  457.         /* growIconSpace true if window has grow icon or a blank space for one. */
  458.  
  459.     wrgn = NewRgn();
  460.  
  461.     if (growIconSpace) {
  462.         rct = portRect;
  463.         rct.left = rct.right  - 15;
  464.         rct.top  = rct.bottom - 15;
  465.         RectRgn(urgn, &rct);
  466.     }
  467.  
  468.     for (i = 0; i < 2; ++i) {
  469.         ctl = (i) ? (*frHndl)->fileState.vScroll : (*frHndl)->fileState.hScroll;
  470.         if (ctl) {
  471.             rct = (*ctl)->contrlRect;
  472.             OffsetRect(&rct, 0, 16384);
  473.             RectRgn(wrgn, &rct);
  474.             UnionRgn(urgn, wrgn, urgn);
  475.         }
  476.     }
  477.  
  478.     l2g.h = l2g.v = 0;
  479.     LocalToGlobal(&l2g);
  480.     OffsetRgn(urgn, l2g.h, l2g.v);
  481.     DisposeRgn(wrgn);
  482.  
  483.     SetPort(oldPort);
  484.     return(urgn);
  485. }
  486.  
  487.  
  488.  
  489. /*****************************************************************************/
  490.  
  491.  
  492.  
  493. #pragma segment Window
  494. void    DoUpdateSeparate(WindowPtr window, RgnHandle *contRgn, RgnHandle *frameRgn)
  495. {
  496.     RgnHandle    urgn, wrgn;
  497.  
  498.     *contRgn = *frameRgn = nil;
  499.     if (!window) return;
  500.  
  501.     urgn = DoCalcFrameRgn(window);
  502.     wrgn = NewRgn();
  503.  
  504.     DiffRgn(((WindowPeek)window)->updateRgn, urgn, wrgn);
  505.     if (!EmptyRgn(wrgn)) {
  506.         *contRgn = wrgn;
  507.         wrgn = NewRgn();
  508.     }
  509.     SectRgn(((WindowPeek)window)->updateRgn, urgn, wrgn);
  510.  
  511.     if (!EmptyRgn(wrgn)) *frameRgn = wrgn;
  512.     else                 DisposeRgn(wrgn);
  513.  
  514.     DisposeRgn(urgn);
  515. }
  516.  
  517.  
  518.  
  519. /*****************************************************************************/
  520.  
  521.  
  522.  
  523. #pragma segment Window
  524. void    BeginContent(WindowPtr window)
  525. {
  526.     RgnHandle    updateRgn, frameRgn;
  527.     Point        contOrg;
  528.  
  529.     GetPort(&gOldPort);
  530.  
  531.     if (window) {
  532.         SetPort(window);
  533.         CopyRgn(updateRgn = ((WindowPeek)window)->updateRgn, gKeepUpdateRgn = NewRgn());
  534.         frameRgn = DoCalcFrameRgn(window);
  535.         DiffRgn(((WindowPeek)window)->contRgn, frameRgn, updateRgn);
  536.         DisposeRgn(frameRgn);
  537.         BeginUpdate(window);
  538.         GetContentOrigin(window, &contOrg);
  539.         SetOrigin(contOrg.h, contOrg.v);
  540.     }
  541. }
  542.  
  543.  
  544.  
  545. /*****************************************************************************/
  546.  
  547.  
  548.  
  549. #pragma segment Window
  550. void    EndContent(WindowPtr window)
  551. {
  552.     if (window) {
  553.         EndUpdate(window);
  554.         CopyRgn(gKeepUpdateRgn, ((WindowPeek)window)->updateRgn);
  555.         SetOrigin(0, 0);
  556.         DisposeRgn(gKeepUpdateRgn);
  557.     }
  558.     SetPort(gOldPort);
  559. }
  560.  
  561.  
  562.  
  563. /*****************************************************************************/
  564.  
  565.  
  566.  
  567. #pragma segment Window
  568. void    AdjustScrollBars(WindowPtr window)
  569. {
  570.     FileRecHndl        frHndl;
  571.     WindowPtr        oldPort;
  572.     ControlHandle    hScroll, vScroll;
  573.     Rect            portRct;
  574.     short            h, v, maxVal, val;
  575.  
  576.     if (!window) return;
  577.  
  578.     oldPort = SetFilePort(frHndl = (FileRecHndl)GetWRefCon(window));
  579.     portRct = window->portRect;
  580.     hScroll = (*frHndl)->fileState.hScroll;
  581.     vScroll = (*frHndl)->fileState.vScroll;
  582.  
  583.     SetOrigin(0, -16384);
  584.  
  585.     h = portRct.right - portRct.left;
  586.     if (vScroll) h -= 15;
  587.     maxVal = (*frHndl)->fileState.hDocSize - h;
  588.     if (hScroll) {
  589.         if (maxVal < (val = GetCtlValue(hScroll))) maxVal = val;
  590.         SetCtlMax(hScroll, maxVal);
  591.     }
  592.     h -= (val = (*frHndl)->fileState.hArrowVal);
  593.     if (h < val) h = val;
  594.     (*frHndl)->fileState.hPageVal = h;
  595.  
  596.     v = portRct.bottom - portRct.top;
  597.     if (hScroll) v -= 15;
  598.     maxVal = (*frHndl)->fileState.vDocSize - v;
  599.     if (vScroll) {
  600.         if (maxVal < (val = GetCtlValue(vScroll))) maxVal = val;
  601.         SetCtlMax(vScroll, maxVal);
  602.     }
  603.     v -= (val = (*frHndl)->fileState.vArrowVal);
  604.     if (v < val) v = val;
  605.     (*frHndl)->fileState.vPageVal = v;
  606.  
  607.     SetOrigin(portRct.left, portRct.top);
  608.     SetPort(oldPort);
  609. }
  610.  
  611.  
  612.  
  613. /*****************************************************************************/
  614.  
  615.  
  616.  
  617. #pragma segment Window
  618. void    GetContentOrigin(WindowPtr window, Point *contOrg)
  619. {
  620.     FileRecHndl        frHndl;
  621.     ControlHandle    ctl;
  622.  
  623.     contOrg->h = contOrg->v = 0;
  624.  
  625.     if (window) {
  626.         frHndl = (FileRecHndl)GetWRefCon(window);
  627.         if (ctl = (*frHndl)->fileState.hScroll) contOrg->h = GetCtlValue(ctl);
  628.         if (ctl = (*frHndl)->fileState.vScroll) contOrg->v = GetCtlValue(ctl);
  629.     }
  630. }
  631.  
  632.  
  633.  
  634. /*****************************************************************************/
  635.  
  636.  
  637.  
  638. #pragma segment Window
  639. void    SetContentOrigin(WindowPtr window, short newh, short newv)
  640. {
  641.     FileRecHndl        frHndl;
  642.     WindowPtr        oldPort;
  643.     ControlHandle    hScroll, vScroll;
  644.     short            max, dh, dv;
  645.     Point            old;
  646.     Rect            portRct;
  647.     RgnHandle        updateRgn;
  648.     
  649.     if (!window) return;
  650.  
  651.     oldPort = SetFilePort(frHndl = (FileRecHndl)GetWRefCon(window));
  652.     hScroll = (*frHndl)->fileState.hScroll;
  653.     vScroll = (*frHndl)->fileState.vScroll;
  654.     GetContentOrigin(window, &old);
  655.  
  656.     SetOrigin(0, -16384);
  657.     if (hScroll) {
  658.         if (newh < 0) newh = 0;
  659.         if (newh > (max = GetCtlMax(hScroll))) newh = max;
  660.         SetCtlValue(hScroll, newh);
  661.     }
  662.     if (vScroll) {
  663.         if (newv < 0) newv = 0;
  664.         if (newv > (max = GetCtlMax(vScroll))) newv = max;
  665.         SetCtlValue(vScroll, newv);
  666.     }
  667.     dh = old.h - newh;
  668.     dv = old.v - newv;
  669.  
  670.     BeginContent(window);
  671.     portRct = window->portRect;
  672.     ScrollRect(&portRct, dh, dv, updateRgn = NewRgn());
  673.     EndContent(window);
  674.     SetOrigin(portRct.left, portRct.top);
  675.  
  676.         /* We want to add the scrolled-in area into the updateRgn.  We
  677.         ** also want to keep the old area.  The old update area is
  678.         ** no longer mapped to the same location, due to the scroll,
  679.         ** so offset it by the amount scrolled.  Once it is offset, we
  680.         ** can add our new update portion to the updateRgn. */
  681.     OffsetRgn(((WindowPeek)window)->updateRgn, dh, dv);
  682.     InvalRgn(updateRgn);
  683.     DisposeRgn(updateRgn);
  684.  
  685.     SetPort(oldPort);        /* Put things back the way we found them. */
  686.     DoCursor();                /* Cursor region may be invalid due to
  687.                             ** content being scrolled.  Force it to
  688.                             ** be recalculated. */
  689. }
  690.  
  691.  
  692.  
  693. /*****************************************************************************/
  694.  
  695.  
  696.  
  697. #pragma segment Window
  698. void    GetContentRect(WindowPtr window, Rect *contRct)
  699. {
  700.     FileRecHndl        frHndl;
  701.     ControlHandle    ctl;
  702.  
  703.     SetRect(contRct, 0, 0, 0, 0);
  704.  
  705.     if (window) {
  706.         frHndl = (FileRecHndl)GetWRefCon(window);
  707.         *contRct = window->portRect;
  708.         if (ctl = (*frHndl)->fileState.hScroll) contRct->bottom -= 15;
  709.         if (ctl = (*frHndl)->fileState.vScroll) contRct->right  -= 15;
  710.     }
  711. }
  712.  
  713.  
  714.  
  715. /*****************************************************************************/
  716.  
  717.  
  718.  
  719. #pragma segment Window
  720. void    SetDocSize(FileRecHndl frHndl, short hSize, short vSize)
  721. {
  722.     if (frHndl) {
  723.         (*frHndl)->fileState.hDocSize = hSize;
  724.         (*frHndl)->fileState.vDocSize = vSize;
  725.         AdjustScrollBars((*frHndl)->fileState.window);
  726.     }
  727. }
  728.  
  729.  
  730.  
  731. /*****************************************************************************/
  732.  
  733.  
  734.  
  735. #pragma segment Window
  736. void    DoImageDocument(FileRecHndl frHndl)
  737. {
  738.     (*((*frHndl)->fileState.imageProc))(frHndl);
  739. }
  740.  
  741.  
  742.  
  743. /*****************************************************************************/
  744.  
  745.  
  746.  
  747. #pragma segment Window
  748. void    DoContentClick(WindowPtr window, EventRecord *event)
  749. {
  750.     FileRecHndl    frHndl;
  751.  
  752.     if (IsAppWindow(window))
  753.         if (frHndl = (FileRecHndl)GetWRefCon(window))
  754.             (*((*frHndl)->fileState.contentClickProc))(window, event);
  755. }
  756.  
  757.  
  758.  
  759. /*****************************************************************************/
  760.  
  761.  
  762.  
  763. #pragma segment Window
  764. void    DoContentKey(WindowPtr window, EventRecord *event)
  765. {
  766.     FileRecHndl    frHndl;
  767.  
  768.     if (IsAppWindow(window))
  769.         if (frHndl = (FileRecHndl)GetWRefCon(window))
  770.             (*((*frHndl)->fileState.contentKeyProc))(window, event);
  771. }
  772.  
  773.  
  774.  
  775.